package br.com.foxinline.manager.iptu;

import br.com.foxinline.enums.*;
import br.com.foxinline.modelo.*;
import br.com.foxinline.servico.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.*;
import java.util.Map.Entry;
import javax.annotation.PostConstruct;
import javax.ejb.EJB;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.primefaces.event.map.OverlaySelectEvent;
import org.primefaces.model.chart.CartesianChartModel;
import org.primefaces.model.chart.ChartSeries;
import org.primefaces.model.chart.PieChartModel;
import org.primefaces.model.map.*;

/**
 *
 * @author roniere
 */
@ViewScoped
@ManagedBean
public class ManagerRelatorioIPTU implements Serializable {

    @EJB
    ImovelServico imovelDao;
    @EJB
    ProprietarioServico proprietarioService;
    @EJB
    DneServico dneService;
    @EJB
    BairroServico bairroServico;
    @EJB
    IptuServico iptuServico;
    private MapModel mapModel;
    private List<Imovel> imoveis;
    private Marker marker;
    private Imovel imovel;
    private String centro;
    private Double latitude = 0D;
    private Double longitude = 0D;
    private PieChartModel pieModelRegular;
    private PieChartModel pieModelIrregular;
    private PieChartModel pieModelQtdImoveis;
    private CartesianChartModel categoryModel;
    private Long max;
    private Bairro bairro;
    private PieChartModel pieModelValorIrregular;

    @PostConstruct
    private void init() {
        imovel = new Imovel();
        bairro = new Bairro();
        centro = "-2.9136, -41.7577";
        mapModel = new DefaultMapModel();
        max = 10L;
        createPieModels();
        createCategoryModel();
    }

    public Long getMax() {
        return max;
    }

    public void setMax(Long max) {
        this.max = max;
    }

    public void plotar() {
        latitude = 0D;
        longitude = 0D;

        LatLng coord = null;
        Polygon polygon = new Polygon();
        for (Imovel i : imoveis) {

            i.setProprietarios(proprietarioService.getProprietarioImovel(i.getId()));

            for (Coordenada c : i.getCoordenadas()) {
                coord = new LatLng(c.getLat(), c.getLog());

                final Marker marker = new Marker(coord, "Proprietário: ");
                marker.setData(i);

                if (i.getProprietarios() == null || i.getProprietarios().isEmpty()) {
                    marker.setTitle("Não existe(m) proprietário(s)");
                }
                for (Proprietario p : i.getProprietarios()) {
                    marker.setTitle(marker.getTitle() + ", " + p.getNome());
                }
                if (i.getCoordenadas() != null && !i.getCoordenadas().isEmpty()) {
                    try {
                        latitude += (latitude + c.getLat()) / i.getCoordenadas().size();
                        longitude += (longitude + c.getLog()) / i.getCoordenadas().size();
                    } catch (Exception e) {
                    }
                }
                mapModel.addOverlay(marker);
            }
        }
        centro = latitude + ", " + longitude;

    }

    public void search() {
        imoveis = imovelDao.find(imovel, null, null);
        mapModel = new DefaultMapModel();
        plotar();
    }

    public List<Bairro> autocompleteBairro(String query) {
        return bairroServico.autocomplete(query);
    }

    public void onMarkerSelect(OverlaySelectEvent event) {
        marker = (Marker) event.getOverlay();
    }

    public Marker getMarker() {
        return marker;
    }

    public void setMarker(Marker marker) {
        this.marker = marker;
    }

    public MapModel getMapModel() {
        return mapModel;
    }

    public void setMapModel(MapModel mapModel) {
        this.mapModel = mapModel;
    }

    public List<Imovel> getImoveis() {
        return imoveis;
    }

    public void setImoveis(List<Imovel> imoveis) {
        this.imoveis = imoveis;
    }

    public Imovel getImovel() {
        return imovel;
    }

    public void setImovel(Imovel imovel) {
        this.imovel = imovel;
    }

    public String getCentro() {
        return centro;
    }

    public void setCentro(String centro) {
        this.centro = centro;
    }

    private void createPieModels() {
        pieModelRegular = new PieChartModel();
        Long qtdIptuTotal = 0L;
        for (String str : dneService.getAllBairro()) {
            Long valorIptu = (Long) iptuServico.valorIptu(false, str, "count");
            if (valorIptu != null) {
                qtdIptuTotal += valorIptu;
            }
            pieModelRegular.set(str, valorIptu);
        }
        pieModelRegular.set("Sem Bairro", ((Long) iptuServico.valorIptu(false, null, "count") - qtdIptuTotal));

        pieModelIrregular = new PieChartModel();
        qtdIptuTotal = 0L;
        for (String str : dneService.getAllBairro()) {
            Long valorIptu = (Long) iptuServico.valorIptu(true, str, "count");
            if (valorIptu != null) {
                qtdIptuTotal += valorIptu;
            }
            pieModelIrregular.set(str, valorIptu);
        }
        pieModelIrregular.set("Sem Bairro", ((Long) iptuServico.valorIptu(true, null, "count") - qtdIptuTotal));

        pieModelValorIrregular = new PieChartModel();
        BigDecimal valorIptuTotal = BigDecimal.ZERO;
        for (String str : dneService.getAllBairro()) {
            BigDecimal valorIptu = (BigDecimal) iptuServico.valorIptu(true, str, "sum");
            if (valorIptu != null) {
                valorIptuTotal = valorIptuTotal.add(valorIptu);
            }
            pieModelValorIrregular.set(str, valorIptu);
        }
        BigDecimal valorTototal = (BigDecimal) iptuServico.valorIptu(true, null, "sum ");
        if (valorIptuTotal == null) {
            pieModelValorIrregular.set("Sem Bairro", (valorTototal.subtract(valorIptuTotal)));
        } else {
            pieModelValorIrregular.set("Sem Bairro", 0);
        }

        pieModelQtdImoveis = new PieChartModel();

        Long totalRegular = (Long) iptuServico.valorIptu(false, null, "count");
        Long totalPendente = (Long) iptuServico.valorIptu(true, null, "count");
        Long total = (Long) iptuServico.valorIptu(null, null, "count");
        pieModelQtdImoveis.set("IPTUs Regulares", totalRegular);
        pieModelQtdImoveis.set("IPTUs Ignorados", totalPendente);
        pieModelQtdImoveis.set("IPTUs Gerados", total);

    }

    public Long qtdImovel() {
        return imovelDao.diagQtdImovel();
    }

    public Long qtdImovelPendente() {
        return imovelDao.diagQtdImovelPendente();
    }

    public PieChartModel getPieModelRegular() {
        return pieModelRegular;
    }

    public void setPieModelRegular(PieChartModel pieModel) {
        this.pieModelRegular = pieModel;
    }

    public PieChartModel getPieModelIrregular() {
        return pieModelIrregular;
    }

    public void setPieModelIrregular(PieChartModel pieModel) {
        this.pieModelIrregular = pieModel;
    }

    public PieChartModel getPieModelQtdImoveis() {
        return pieModelQtdImoveis;
    }

    public void setPieModelQtdImoveis(PieChartModel pieModelQtdImoveis) {
        this.pieModelQtdImoveis = pieModelQtdImoveis;
    }

    private void createCategoryModel() {
        categoryModel = new CartesianChartModel();

        for (Patrimonio p : Patrimonio.values()) {
            Imovel imovelFind = new Imovel();
            ChartSeries boys = new ChartSeries();
            boys.setLabel(p.getNome());
            imovelFind.setPatrimonio(p);
            Long resu = imovelDao.diagFindImoveis(imovelFind, null, null);

            if (resu > max) {
                max = resu;
            }

            boys.set("", resu);
            categoryModel.addSeries(boys);
        }

        max += 10;
    }

    public CartesianChartModel getCategoryModel() {
        return categoryModel;
    }

    public PieChartModel getPieModelValorIrregular() {
        return pieModelValorIrregular;
    }

    public void setPieModelValorIrregular(PieChartModel pieModelValorIrregular) {
        this.pieModelValorIrregular = pieModelValorIrregular;
    }

    public void setCategoryModel(CartesianChartModel categoryModel) {
        this.categoryModel = categoryModel;
    }

    public Bairro getBairro() {
        return bairro;
    }

    public void setBairro(Bairro bairro) {
        this.bairro = bairro;
    }

    public ArrayList<Entry<String, BigDecimal>> getValores() {
        HashMap x = new HashMap<String, Long>();
        x.put("Regular", (BigDecimal) iptuServico.valorIptu(false, null, "sum"));
        x.put("Ignorado", (BigDecimal) iptuServico.valorIptu(true, null, "sum"));
        x.put("Total", (BigDecimal) iptuServico.valorIptu(null, null, "sum"));
        Set<Map.Entry<String, BigDecimal>> valores = x.entrySet();
        return new ArrayList<Map.Entry<String, BigDecimal>>(valores);
    }
}
